package com.vader.boot.aspect;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;

/**
 * @author Vader
 * @date 2022/5/25
 **/
@Slf4j
public class $CglibProxyTest extends CglibProxyTest{

    private MethodInterceptor methodInterceptor;

    public void setMethodInterceptor(MethodInterceptor methodInterceptor) {
        this.methodInterceptor = methodInterceptor;
    }

    static Method save0;
    static Method save1;
    static Method save2;
    static MethodProxy save0P;
    static MethodProxy save1P;
    static MethodProxy save2P;
    static {
        try {
            save0 = CglibProxyTest.class.getMethod("save");
            save1 = CglibProxyTest.class.getMethod("save",int.class);
            save2 = CglibProxyTest.class.getMethod("save",long.class);
            save0P = MethodProxy.create(CglibProxyTest.class,$CglibProxyTest.class,"()V","save","saveSuper");
            save1P = MethodProxy.create(CglibProxyTest.class,$CglibProxyTest.class,"(I)V","save","saveSuper");
            save2P = MethodProxy.create(CglibProxyTest.class,$CglibProxyTest.class,"(J)V","save","saveSuper");
        }catch (NoSuchMethodException e){
            throw new NoSuchMethodError(e.getMessage());
        }
    }

    public void saveSuper(){
        super.save();
    }

    public void saveSuper(int i){
        super.save(i);
    }

    public void saveSuper(long l){
        super.save(l);
    }

    @Override
    public void save(){
        try {
            methodInterceptor.intercept(this,save0,new Object[0],save0P);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    @Override
    public void save(int i){
        try {
            methodInterceptor.intercept(this,save1,new Object[]{i},save1P);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    @Override
    public void save(long l){
        try {
            methodInterceptor.intercept(this,save2,new Object[]{l},save2P);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

}
